package com.nineclock.auth.config;

import com.nineclock.auth.intergration.entity.IntergrationAuthenticationEntity;
import com.nineclock.auth.intergration.processor.AuthenticationProcessor;
import com.nineclock.auth.intergration.threadLocal.IntergrationAuthenticationHolder;
import com.nineclock.auth.intergration.threadLocal.UserHolder;
import com.nineclock.common.constant.NcConstant;
import com.nineclock.common.entity.Result;
import com.nineclock.common.entity.UserInfo;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.JsonUtils;
import com.nineclock.system.dto.SysCompanyUserDTO;
import com.nineclock.system.dto.SysRoleDTO;
import com.nineclock.system.dto.SysUserDTO;
import com.nineclock.system.feign.SysCompanyUserFeign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;

@Component
@Slf4j
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private List<AuthenticationProcessor> processors;
    @Autowired
    private SysCompanyUserFeign sysCompanyUserFeign;
    //明文密码为 123456
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        IntergrationAuthenticationEntity entity = IntergrationAuthenticationHolder.get();
        AuthenticationProcessor authenticationProcessor = chooseProcessor(entity);
        if (authenticationProcessor ==null){
            throw new NcException(ResponseEnum.SERVER_ERROR);
        }
        log.info("选择的认证处理器为：" + authenticationProcessor.getClass().getSimpleName());
        SysUserDTO sysUserDTO = authenticationProcessor.authenticate(entity);
        UserInfo userInfo = BeanHelper.copyProperties(sysUserDTO,UserInfo.class);
        //认证完善
        String clientId = entity.getAuthParameter("client_id");
        String companyIdStr = entity.getAuthParameter("company_id");
        Long companyId = StringUtils.isEmpty(companyIdStr) ? null : Long.valueOf(companyIdStr);
        if (clientId.equals("pc_client")){
            List<SysCompanyUserDTO> companyUser = sysCompanyUserFeign.queryCompanyUser(sysUserDTO.getId(), companyId).getData();
            if (CollectionUtils.isEmpty(companyUser)){
                throw new NcException(ResponseEnum.USER_NOT_JOIN_COMPANY);
            }
            Boolean isAdmin = checkAdmin(companyUser);
            if (!isAdmin){
                throw new NcException(ResponseEnum.USER_NOT_COMPANY_ADMIN);
            }
            if (companyUser.size() == 1 || companyId != null){
                SysCompanyUserDTO userDTO = companyUser.get(0);
                wrapper(userDTO,userInfo);
            }
        }else {  // APP端认证

            if(companyId == null){ // 如果没有传递企业id，获取用户最后一次登录的企业id
                companyId = sysUserDTO.getLastLoginCompanyId();
            }
            // 调用系统微服务接口，根据用户id、企业id得到员工列表
            List<SysCompanyUserDTO> companyUserDTOList = sysCompanyUserFeign.queryCompanyUser(sysUserDTO.getId(), companyId).getData();

            if (CollectionUtils.isEmpty(companyUserDTOList)) {
                throw new NcException(ResponseEnum.USER_NOT_JOIN_COMPANY);
            }

            SysCompanyUserDTO sysCompanyUserDTO = companyUserDTOList.get(0);

            // 封装员工信息
            wrapper(sysCompanyUserDTO, userInfo);

        }
        //end

        UserHolder.set(userInfo);
        return User.withUsername(JsonUtils.toString(userInfo)).password(sysUserDTO.getPassword()).authorities(userInfo.getGrantedAuthorities()).build();
        /*return User.withUsername(username)
                .password("$2a$10$yRkoWX3dbPF8TX4KhB9kC.C4XiOJ4ThD/YQoersDtZjzJUYp4Rs7a")
                .authorities("ROLE_ADMIN","P1").build();*/
    }
    private void wrapper(SysCompanyUserDTO sysCompanyUserDTO, UserInfo userInfo) {
        userInfo.setCompanyId(sysCompanyUserDTO.getCompanyId());
        userInfo.setCompanyName(sysCompanyUserDTO.getCompanyName());
        userInfo.setDepartmentId(sysCompanyUserDTO.getDepartmentId());
        userInfo.setDepartmentName(sysCompanyUserDTO.getDepartmentName());
        userInfo.setCompanyUserId(sysCompanyUserDTO.getId());
        userInfo.setPost(sysCompanyUserDTO.getPost());
        userInfo.setWorkNumber(sysCompanyUserDTO.getWorkNumber());
        userInfo.setTimeEntry(sysCompanyUserDTO.getTimeEntry());
        userInfo.setEnable(true);

        // 用户的权限
        if (!CollectionUtils.isEmpty(sysCompanyUserDTO.getGrantedAuthorities())) {
            userInfo.setGrantedAuthorities(sysCompanyUserDTO.getGrantedAuthorities());
        }
    }

    private Boolean checkAdmin(List<SysCompanyUserDTO> companyUser) {
        for (SysCompanyUserDTO sysCompanyUserDTO : companyUser) {
            List<SysRoleDTO> roles = sysCompanyUserDTO.getRoles();
            if (!CollectionUtils.isEmpty(roles)){
                for (SysRoleDTO role : roles) {
                    if (role.getRoleName().equals(NcConstant.ADMIN_ROLE_SYS)){
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public AuthenticationProcessor chooseProcessor(IntergrationAuthenticationEntity entity){
        for (AuthenticationProcessor processor : processors) {
            if (processor.support(entity)){
                return processor;
            }
        }
        return null;
    }

}